home *** CD-ROM | disk | FTP | other *** search
Text File | 1987-07-05 | 58.6 KB | 2,244 lines |
- Article 47 of comp.sources.games:
- Path: ncrcce!rd1632!ncrlnk!ncrcae!ece-csc!mcnc!seismo!rochester!cornell!uw-beaver!tektronix!tekgen!tekred!games-request
- From: games-request@tekred.TEK.COM
- Newsgroups: comp.sources.games
- Subject: v01i073: xtrek - multiplayer space war game for X-windows, Part01/06
- Message-ID: <1366@tekred.TEK.COM>
- Date: 2 Jul 87 19:09:41 GMT
- Sender: billr@tekred.TEK.COM
- Lines: 2230
- Approved: billr@tekred.TEK.COM
-
- Submitted by: Chris Guthrie <chris%ic.Berkeley.EDU@ucbvax.berkeley.edu>
- Comp.sources.games: Volume 1, Issue 73
- Archive-name: xtrek/Part01
-
- [The following note is from the author. (I sure wish I had
- a system with X-windows to play all these neat games!) -br]
-
- [[xtrek is a game based on the x windowing system. Typically,
- I've been distributing it through ftp, but I'm getting too
- many requests from people out in uucp land, so I figure that
- sources.games would be appropriate. People will need to have
- X and sysV shared memory to run the game. We have it running
- on Ultrix, Sun 3.2, and HP-UX 5.2 machines.]]
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 1 (of 6)."
- # Contents: README MANIFEST daemon.c rmove.c xtrek.6
- # Wrapped by billr@tekred on Thu Jul 2 10:26:27 1987
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f README -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"README\"
- else
- echo shar: Extracting \"README\" \(5259 characters\)
- sed "s/^X//" >README <<'END_OF_README'
- XThis explains quickly how to run xtrek on a ultrix,
- XSun 3.20, or HP-UX 5.2 system. Note that other
- Xoperating systems will probably require fiddling.
- XThere are notes for various operating systems below.
- XThere is also a list of recent changes.
- X
- XIt is important that the system V shared memory
- Xsegments are actually compiled into your kernel on
- Xthe server machine. The clients just need X.
- X
- XCreate an appropriate directory for it. The defs.h
- Xfile contains the paths to this directory. If you
- Xdon't want it in /usr/games/lib/xtrek, change this
- Xfile.
- X
- XA "make install" will perform the following steps for you.
- XIf you don't want xtrek and daemon to be suid to root
- Xor you don't like the choice of directories, either
- Xchange DESTDIR, XTREKDIR and XTREKOWNER in the Makefile
- Xor perform these steps by hand:
- X
- X Run make. Install xtrek in /usr/games. Robot and
- X daemon must be in /usr/games/lib/xtrek. Create the
- X files .motd, .scores, and .planets in
- X /usr/games/lib/xtrek.
- X
- X Xtrek and the daemon must all be setuid
- X to someone who has write permission on these files.
- X Root is fine. There are no real security holes in
- X the game. If you want to avoid this, take out the
- X shared memory chmoding and make the dot files writable.
- X
- XIf you want to change constants in the game, it is
- Xpretty well set up to allow tweaking. Most of the
- Xconstants are in defs.h. Player constants were defined
- Xin getship.c in plans for a future custom designed ship
- Xoption.
- X
- Xnroff -me the document and put it somewhere useful.
- X
- XHP-UX notes:
- X
- XAlthought I have compiled and run this version of xtrek on
- Xan HP-UX 5.2 system, there are some things to be aware of.
- XFirst, my system was a 320. If you have access to a 840 it
- Xwould clearly be a better choice as a server. It would also
- Xprovide the wait3 function needed in some of the code. I don't
- Xknow how the wait's I've put into the code will work out.
- X
- XA 320 system, while being sufficient as a display for the game,
- Xwould probably not work well as a server.
- X
- XSun notes:
- X
- XSome code was added to prevent people from holding down the
- X't' key and generating fields of torps with the auto-repeat
- Xmode. This uses the timer for the xevents and it's not clear
- Xthat the timer works everywhere.
- X
- XThere is one clear bug in the sun Xlib server that can make
- Xtorpedoes occasionnally fail to fire. If you want to fix this
- Xbug, replace the line of code in libsun/events.c:
- X
- X xe->vse_time = (se->ie_time.tv_usec/10000 + se->ie_time.tv_sec);
- X
- Xwith
- X
- X xe->vse_time = (se->ie_time.tv_usec/10000 + se->ie_time.tv_sec*100);
- X
- XIt appears twice so get 'em both. Note that this stuff is in the source
- Xto libX.a for the suns.
- X
- XApollo Notes:
- X
- XWe don't have an apollo to test the code out, but the following lines
- Xin the xlib code scare me:
- X
- X /* this needs to be replaced with a "real" timestamp */
- X xe->vse_time += 1;
- X
- XI suspect that on an apollo, only one torp in ten will actually be fired.
- XSee the Sun notes above for more information.
- X
- XUltrix notes:
- X
- XBefore running make, look for random.o. I found
- Xthat the ultrix library version wasn't very random,
- Xso I substituted the 4.3 one which worked better.
- XLicensing agreements being what they are, the
- Xversion in this directory just links against
- Xwhatever random.o is in libc.a.
- X
- XIf you have the 4.3 random.o (or .c), just restore
- Xthe commented-out reference to random.o in the Makefile
- Xand it will link against your copy. If we ever find a
- Xgood public domain rand() function, this problem will
- Xgo away.
- X
- X
- XChanges from version 3.0 to version 4.0:
- X
- XPlayers cannot jump teams once in. They must quit and rejoin
- Xto change teams.
- X
- XWhen a team loses its last planet, they cannot hold a coup for 30
- Xminutes to an hour of play time.
- X
- XThere is an independent team that controls all planets with zero
- Xarmies.
- X
- XFuel cannot go negative now.
- X
- XCertain deaths will force you to exit the game completely.
- X
- XSome colors have been changed.
- X
- XPlayers may not bomb their own planets. (Their crews have wives and
- Xchildren down there....)
- X
- XSince sys V compatibility seems to show up in most 4.3 based include
- Xfiles, I've gone over to the sys V names of some things like
- XSIGCHLD -> SIGCLD.
- X
- XFixed a bug with showstats that crashed in watch mode.
- X
- XThere have been a number of changes to 'improve' play. Not
- Xeveryone agrees that they are for the better. Ships now
- Xturn one warp faster. Fuel is used by the engines -- you
- Xdon't gain fuel at warp 5 anymore.
- X
- XEvents now go through info windows properly.
- X
- XThe special font effects occur in the info windows.
- X
- XThe space key will now also close all special windows.
- X
- XYou cannot repair and use transporters at the same time.
- X
- XThere are a number of optimizations. Hardcoding the lengths
- Xof planetnames reduced the number of calls to strlen. The
- Xstatus line is now drawn by hand to save calls to doprnt().
- XAlso, the characters up on the map window for each ship are
- Xstored in the ship's data structure to avoid more calls to
- Xdoprnt().
- X
- XRobots are a little smarter and slightly more aggressive. This
- Xwas meant to stop people from darting in and out while taking
- Xperiphery planets.
- X
- XOverheated weapons can't be wrapped around.
- X
- XPeople who hold down the 't' key to get a burst of torps are
- Xin for a surprise. Torps cannot be fired faster than one every
- Xtenth of a second.
- X
- END_OF_README
- if test 5259 -ne `wc -c <README`; then
- echo shar: \"README\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f MANIFEST -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"MANIFEST\"
- else
- echo shar: Extracting \"MANIFEST\" \(1374 characters\)
- sed "s/^X//" >MANIFEST <<'END_OF_MANIFEST'
- X File Name Archive # Description
- X-----------------------------------------------------------
- X MANIFEST 1 This shipping list
- X Makefile 4
- X README 1
- X bitmaps.h 2
- X clock.bitmap 5
- X colors.c 5
- X coup.c 5
- X daemon.c 1
- X data.c 5
- X data.h 5
- X death.c 5
- X defs.h 5
- X detonate.c 3
- X dmessage.c 5
- X doc 2
- X enter.c 5
- X getship.c 6
- X inform.c 4
- X input.c 3
- X interface.c 5
- X main.c 4
- X newwin.c 3
- X orbit.c 5
- X phaser.c 5
- X planetlist.c 5
- X planets.h 5
- X playerlist.c 2
- X pstats.c 4
- X redraw.c 3
- X rmove.c 1
- X robot.c 5
- X scores.c 5
- X sintab.c 4
- X smessage.c 4
- X startdaemon.c 5
- X stats.c 4
- X struct.h 4
- X torp.c 5
- X util.c 5
- X war.c 4
- X warning.c 6
- X xtrek.6 1
- END_OF_MANIFEST
- if test 1374 -ne `wc -c <MANIFEST`; then
- echo shar: \"MANIFEST\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f daemon.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"daemon.c\"
- else
- echo shar: Extracting \"daemon.c\" \(29846 characters\)
- sed "s/^X//" >daemon.c <<'END_OF_daemon.c'
- X
- X/*
- X
- X Copyright (c) 1986 Chris Guthrie
- X
- XPermission to use, copy, modify, and distribute this
- Xsoftware and its documentation for any purpose and without
- Xfee is hereby granted, provided that the above copyright
- Xnotice appear in all copies and that both that copyright
- Xnotice and this permission notice appear in supporting
- Xdocumentation. No representations are made about the
- Xsuitability of this software for any purpose. It is
- Xprovided "as is" without express or implied warranty.
- X
- X*/
- X
- X#include <X/Xlib.h>
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/ipc.h>
- X#include <sys/shm.h>
- X#ifdef hpux
- X#include <time.h>
- X#else hpux
- X#include <sys/time.h>
- X#endif hpux
- X#include <sys/file.h>
- X#ifndef hpux
- X#include <sys/wait.h>
- X#endif hpux
- X#include <sys/ioctl.h>
- X#include <signal.h>
- X#include <setjmp.h>
- X#include <math.h>
- X#include "defs.h"
- X#include "struct.h"
- X#include "data.h"
- X#include "planets.h"
- X
- X#ifdef hpux
- X#define bcopy(from, to, length) memcpy((to), (from), (length))
- X#endif hpux
- X
- X#define fuse(X) ((ticks % (X)) == 0)
- X/* Run the game */
- X
- Xlong random();
- Xlong lseek();
- Xstatic struct itimerval udt;
- Xstatic int shmid;
- X
- Xstatic int debug = 0;
- Xstatic int ticks = 0;
- Xstatic int plfd;
- X
- Xjmp_buf env;
- X
- Xstatic int tcount[MAXTEAM + 1];
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar **argv;
- X{
- X register int i;
- X int shmemKey = PKEY;
- X struct memory *sharedMemory;
- X struct shmid_ds smbuf;
- X int x = 0;
- X int move();
- X int reaper();
- X int freemem();
- X
- X if (argc > 1)
- X debug = 1;
- X
- X srandom(getpid());
- X if (!debug) {
- X for (i = 0; i < NSIG; i++) {
- X (void) signal(i, freemem);
- X }
- X detach();
- X }
- X
- X /* Kill any existing segments */
- X
- X if ((shmid = shmget(shmemKey, 0, 0)) >= 0) {
- X fprintf(stderr, "Killing existing segment\n");
- X shmctl(shmid, IPC_RMID, (struct shmid_ds *) 0);
- X }
- X
- X shmid = shmget(shmemKey, sizeof(struct memory), IPC_CREAT | 0777);
- X if (shmid < 0) {
- X perror("can't open shared memory");
- X exit (1);
- X }
- X /* Hose Ed's robots */
- X shmctl(shmid, IPC_STAT, &smbuf);
- X smbuf.shm_perm.uid = geteuid();
- X smbuf.shm_perm.mode = 0700;
- X shmctl(shmid, IPC_SET, &smbuf);
- X
- X sharedMemory = (struct memory *) shmat(shmid, 0, 0);
- X if (sharedMemory == (struct memory *) -1) {
- X perror("shm attach");
- X exit (1);
- X }
- X players = sharedMemory->players;
- X torps = sharedMemory->torps;
- X status = sharedMemory->status;
- X planets = sharedMemory->planets;
- X phasers = sharedMemory->phasers;
- X mctl = sharedMemory->mctl;
- X messages = sharedMemory->messages;
- X
- X for (i = 0; i < MAXPLAYER; i++)
- X players[i].p_status = PFREE;
- X
- X plfd = open(PLFILE, O_RDWR, 0777);
- X if (plfd < 0) {
- X fprintf(stderr, "No planet file. Restarting galaxy\n");
- X bcopy(pdata, planets, sizeof(pdata));
- X for (i = 0; i < 40; i++) {
- X if (planets[i].pl_flags & PLHOME)
- X planets[i].pl_flags |= (PLREPAIR|PLFUEL);
- X if (random() % 4 == 0)
- X planets[i].pl_flags |= PLREPAIR;
- X if (random() % 2 == 0)
- X planets[i].pl_flags |= PLFUEL;
- X }
- X }
- X else {
- X if (read(plfd, (char *) planets, sizeof(pdata)) != sizeof(pdata)) {
- X fprintf(stderr, "Planet file wrong size. Restarting galaxy\n");
- X bcopy(pdata, planets, sizeof(pdata));
- X for (i = 0; i < 40; i++) {
- X if (planets[i].pl_flags & PLHOME)
- X planets[i].pl_flags |= (PLREPAIR|PLFUEL);
- X if (random() % 4 == 0)
- X planets[i].pl_flags |= PLREPAIR;
- X if (random() % 2 == 0)
- X planets[i].pl_flags |= PLFUEL;
- X }
- X }
- X }
- X
- X status->active = 0;
- X
- X (void) signal(SIGCLD, reaper);
- X
- X (void) signal(SIGALRM, move);
- X udt.it_interval.tv_sec = 0;
- X udt.it_interval.tv_usec = UPDATE;
- X udt.it_value.tv_sec = 0;
- X udt.it_value.tv_usec = UPDATE;
- X (void) setitimer(ITIMER_REAL, &udt, (struct itimerval *) 0);
- X
- X (void) setjmp(env);
- X
- X while (1) {
- X pause();
- X if (debug) {
- X if (!(++x % 50))
- X printf("Mark %d\n", x);
- X }
- X }
- X}
- X
- Xdetach()
- X{
- X int fd;
- X
- X#ifdef hpux
- X setpgrp();
- X#else hpux
- X fd = open("/dev/tty", O_RDWR, 0);
- X if (fd < 0)
- X return;
- X (void) ioctl(fd, TIOCNOTTY, (char *) NULL);
- X (void) close(fd);
- X#endif hpux
- X}
- X
- X/* These specify how often special actions will take place in
- X UPDATE units (0.10 seconds, currently.)
- X*/
- X
- X#define PLAYERFUSE 1
- X#define TORPFUSE 1
- X#define PHASERFUSE 1
- X#define TEAMFUSE 5
- X#define PLFIGHTFUSE 5
- X#define BEAMFUSE 10
- X#define SYNCFUSE 3000
- X#define PLANETFUSE 600
- X
- X#define GHOSTTIME (10 * 1000000 / UPDATE) /* 10 secs */
- X#define OUTFITTIME (2 * AUTOQUIT * 1000000 / UPDATE) /* 2 * AQ secs */
- X
- Xnplayers = 0;
- Xdietime = -1;
- X
- Xmove()
- X{
- X if (++ticks == dietime) /* no player for 1 minute. kill self */
- X freemem();
- X if (fuse(PLAYERFUSE)) {
- X udplayers();
- X }
- X if (fuse(TORPFUSE)) {
- X udtorps();
- X }
- X if (fuse(PHASERFUSE)) {
- X udphaser();
- X }
- X if (fuse(TEAMFUSE)) {
- X teamtimers();
- X }
- X if (fuse(PLFIGHTFUSE)) {
- X plfight();
- X }
- X if (fuse(BEAMFUSE)) {
- X beam();
- X }
- X if (fuse(SYNCFUSE)) {
- X save_planets();
- X }
- X if (fuse(PLANETFUSE)) {
- X udplanets();
- X }
- X}
- X
- Xudplayers()
- X{
- X register int i, k;
- X register struct player *j;
- X int maxspeed;
- X
- X nplayers = 0;
- X tcount[FED] = tcount[ROM] = tcount[KLI] = tcount[ORI] = 0;
- X for (i = status->active = 0, j = &players[i]; i < MAXPLAYER; i++, j++) {
- X switch (j->p_status) {
- X case POUTFIT:
- X if (++(j->p_ghostbuster) > OUTFITTIME)
- X j->p_status = PFREE;
- X continue;
- X case PFREE:
- X nplayers++;
- X j->p_ghostbuster = 0; /* stop from hosing new players */
- X continue;
- X case PDEAD:
- X if (--j->p_explode <= 0) { /* Ghost Buster */
- X j->p_status = PFREE;
- X }
- X continue;
- X case PEXPLODE:
- X j->p_updates++;
- X j->p_flags &= ~PFCLOAK;
- X if (j->p_explode == (10/PLAYERFUSE))
- X blowup(j); /* damage everyone else around */
- X if (--j->p_explode <= 0) {
- X j->p_status = PDEAD;
- X j->p_explode = 600/PLAYERFUSE; /* set ghost buster */
- X }
- X break;
- X case PALIVE:
- X if (++(j->p_ghostbuster) > GHOSTTIME) {
- X j->p_status = PEXPLODE;
- X j->p_explode = 10/PLAYERFUSE;
- X ghostmess(j);
- X /* j->p_stats.st_losses++; */
- X j->p_whydead = KGHOST;
- X j->p_whodead = i;
- X }
- X
- X status->active += (1<<i);
- X tcount[j->p_team]++;
- X j->p_updates++;
- X
- X /* cool weapons */
- X j->p_wtemp -= 2;
- X if (j->p_wtemp < 0)
- X j->p_wtemp = 0;
- X if (j->p_flags & PFWEP) {
- X if (--j->p_wtime <= 0)
- X j->p_flags &= ~PFWEP;
- X }
- X else if (j->p_wtemp > 1000) {
- X if (!(random() % 40)) {
- X j->p_flags |= PFWEP;
- X j->p_wtime = ((random() % 150) + 100) / PLAYERFUSE;
- X }
- X }
- X /* cool engine */
- X j->p_etemp -= 5;
- X if (j->p_etemp < 0)
- X j->p_etemp = 0;
- X if (j->p_flags & PFENG) {
- X if (--j->p_etime <= 0)
- X j->p_flags &= ~PFENG;
- X }
- X else if (j->p_etemp > 1000) {
- X if (!(random() % 40)) {
- X j->p_flags |= PFENG;
- X j->p_etime = ((random() % 150) + 100) / PLAYERFUSE;
- X j->p_desspeed = 0;
- X }
- X }
- X
- X /* Add fuel */
- X if ((j->p_flags & PFORBIT) &&
- X (planets[j->p_planet].pl_flags & PLFUEL) &&
- X (!(planets[j->p_planet].pl_owner
- X & (j->p_swar | j->p_hostile)))) {
- X j->p_fuel += 8 * j->p_ship.s_recharge;
- X }
- X else
- X j->p_fuel += 2 * j->p_ship.s_recharge;
- X
- X if (j->p_fuel > j->p_ship.s_maxfuel)
- X j->p_fuel = j->p_ship.s_maxfuel;
- X if (j->p_fuel < 0) {
- X j->p_desspeed = 0;
- X j->p_flags &= ~PFCLOAK;
- X }
- X
- X /* repair shields */
- X if (j->p_shield < 100) {
- X if ((j->p_flags & PFREPAIR) && (j->p_speed == 0)) {
- X j->p_subshield += j->p_ship.s_repair * 4;
- X if ((j->p_flags & PFORBIT) &&
- X (planets[j->p_planet].pl_flags & PLREPAIR) &&
- X (!(planets[j->p_planet].pl_owner
- X & (j->p_swar | j->p_hostile)))) {
- X j->p_subshield += j->p_ship.s_repair * 4;
- X }
- X }
- X else
- X j->p_subshield += j->p_ship.s_repair * 2;
- X if (j->p_subshield / 1000) {
- X j->p_shield += j->p_subshield / 1000;
- X j->p_subshield %= 1000;
- X }
- X if (j->p_shield > 100) {
- X j->p_shield = 100;
- X j->p_subshield = 0;
- X }
- X }
- X
- X /* repair damage */
- X if (j->p_damage && !(j->p_flags & PFSHIELD)) {
- X if ((j->p_flags & PFREPAIR) && (j->p_speed == 0)) {
- X j->p_subdamage += j->p_ship.s_repair * 2;
- X if ((j->p_flags & PFORBIT) &&
- X (planets[j->p_planet].pl_flags & PLREPAIR) &&
- X (!(planets[j->p_planet].pl_owner
- X & (j->p_swar | j->p_hostile)))) {
- X j->p_subdamage += j->p_ship.s_repair * 2;
- X }
- X }
- X else
- X j->p_subdamage += j->p_ship.s_repair;
- X if (j->p_subdamage / 1000) {
- X j->p_damage -= j->p_subdamage / 1000;
- X j->p_subdamage %= 1000;
- X }
- X if (j->p_damage < 0) {
- X j->p_damage = 0;
- X j->p_subdamage = 0;
- X }
- X }
- X
- X /* Charge for cloaking */
- X if (j->p_flags & PFCLOAK) {
- X if (j->p_fuel < j->p_ship.s_cloakcost) {
- X j->p_flags &= ~PFCLOAK;
- X }
- X else {
- X j->p_fuel -= j->p_ship.s_cloakcost;
- X }
- X }
- X
- X /* Move Player in orbit */
- X if (j->p_flags & PFORBIT) {
- X j->p_dir += 2;
- X j->p_desdir = j->p_dir;
- X j->p_x = planets[j->p_planet].pl_x + ORBDIST
- X * Cos[(unsigned char) (j->p_dir - (unsigned char) 64)];
- X j->p_y = planets[j->p_planet].pl_y + ORBDIST
- X * Sin[(unsigned char) (j->p_dir - (unsigned char) 64)];
- X }
- X
- X /* Move player through space */
- X else {
- X
- X if (j->p_dir != j->p_desdir)
- X changedir(j);
- X
- X /* Alter speed */
- X maxspeed = 10 - j->p_damage/10;
- X if (j->p_desspeed > maxspeed)
- X j->p_desspeed = maxspeed;
- X if (j->p_flags & PFENG)
- X j->p_desspeed = 0;
- X
- X if (j->p_desspeed > j->p_speed) {
- X j->p_subspeed += j->p_ship.s_accint;
- X }
- X if (j->p_desspeed < j->p_speed) {
- X j->p_subspeed -= j->p_ship.s_decint;
- X }
- X if (j->p_subspeed / 1000) {
- X j->p_speed += j->p_subspeed / 1000;
- X j->p_subspeed /= 1000;
- X if (j->p_speed < 0)
- X j->p_speed = 0;
- X if (j->p_speed > j->p_ship.s_maxspeed)
- X j->p_speed = j->p_ship.s_maxspeed;
- X }
- X /* Charge for speed */
- X
- X if (j->p_fuel < (j->p_ship.s_warpcost * j->p_speed)) {
- X j->p_desspeed = 0;
- X }
- X else {
- X j->p_fuel -= j->p_ship.s_warpcost * j->p_speed;
- X j->p_etemp += j->p_speed;
- X }
- X
- X j->p_x += (double) j->p_speed * Cos[j->p_dir] * WARP1;
- X j->p_y += (double) j->p_speed * Sin[j->p_dir] * WARP1;
- X
- X /* Bounce off the side of the galaxy */
- X if (j->p_x < 0) {
- X j->p_x = -j->p_x;
- X if (j->p_dir == 192)
- X j->p_dir = j->p_desdir = 64;
- X else
- X j->p_dir = j->p_desdir = 64 - (j->p_dir - 192);
- X }
- X else if (j->p_x > GWIDTH) {
- X j->p_x = GWIDTH - (j->p_x - GWIDTH);
- X if (j->p_dir == 64)
- X j->p_dir = j->p_desdir = 192;
- X else
- X j->p_dir = j->p_desdir = 192 - (j->p_dir - 64);
- X }
- X if (j->p_y < 0) {
- X j->p_y = -j->p_y;
- X if (j->p_dir == 0)
- X j->p_dir = j->p_desdir = 128;
- X else
- X j->p_dir = j->p_desdir = 128 - j->p_dir;
- X }
- X else if (j->p_y > GWIDTH) {
- X j->p_y = GWIDTH - (j->p_y - GWIDTH);
- X if (j->p_dir == 128)
- X j->p_dir = j->p_desdir = 0;
- X else
- X j->p_dir = j->p_desdir = 0 - (j->p_dir - 128);
- X }
- X }
- X
- X /* Set player's alert status */
- X#define YRANGE ((GWIDTH)/5)
- X#define RRANGE ((GWIDTH)/10)
- X j->p_flags |= PFGREEN;
- X j->p_flags &= ~(PFRED|PFYELLOW);
- X for (k = 0; k < MAXPLAYER; k++) {
- X int dx, dy, dist;
- X if ((players[k].p_status != PALIVE) ||
- X ((!((j->p_swar | j->p_hostile) & players[k].p_team)) &&
- X (!((players[k].p_swar | players[k].p_hostile) &
- X j->p_team)))) {
- X continue;
- X }
- X else if (j == &players[k]) {
- X continue;
- X }
- X else {
- X dx = j->p_x - players[k].p_x;
- X dy = j->p_y - players[k].p_y;
- X if (ABS(dx) > YRANGE || ABS(dy) > YRANGE)
- X continue;
- X dist = dx * dx + dy * dy;
- X if (dist < RRANGE * RRANGE) {
- X j->p_flags |= PFRED;
- X j->p_flags &= ~(PFGREEN|PFYELLOW);
- X }
- X else if ((dist < YRANGE * YRANGE) &&
- X (!(j->p_flags & PFRED))) {
- X j->p_flags |= PFYELLOW;
- X j->p_flags &= ~(PFGREEN|PFRED);
- X }
- X }
- X }
- X break;
- X } /* end switch */
- X }
- X if (nplayers == MAXPLAYER) {
- X if (dietime == -1)
- X dietime = ticks + 600 / PLAYERFUSE;
- X }
- X else {
- X dietime = -1;
- X }
- X}
- Xchangedir(sp)
- Xstruct player *sp;
- X{
- X unsigned int ticks;
- X
- X if (sp->p_speed == 0) {
- X sp->p_dir = sp->p_desdir;
- X sp->p_subdir = 0;
- X }
- X else {
- X sp->p_subdir += sp->p_ship.s_turns / (1 << sp->p_speed);
- X ticks = sp->p_subdir / 1000;
- X if (ticks) {
- X if (ticks > ABS(sp->p_dir - sp->p_desdir))
- X sp->p_dir = sp->p_desdir;
- X else if ((unsigned char) (sp->p_dir - sp->p_desdir) > 127)
- X sp->p_dir += ticks;
- X else
- X sp->p_dir -= ticks;
- X sp->p_subdir %= 1000;
- X }
- X }
- X}
- X
- Xudtorps()
- X{
- X register int i;
- X register struct torp *j;
- X
- X for (i = 0, j = &torps[i]; i < MAXPLAYER * MAXTORP; i++, j++) {
- X switch (j->t_status) {
- X case TFREE:
- X continue;
- X case TMOVE:
- X case TSTRAIGHT:
- X j->t_x += (double) j->t_speed * Cos[j->t_dir] * WARP1;
- X if (j->t_x < 0) {
- X j->t_x = 0;
- X explode(j);
- X break;
- X }
- X else if (j->t_x > GWIDTH) {
- X j->t_x = GWIDTH;
- X explode(j);
- X break;
- X }
- X j->t_y += (double) j->t_speed * Sin[j->t_dir] * WARP1;
- X if (j->t_y < 0) {
- X j->t_y = 0;
- X explode(j);
- X break;
- X }
- X else if (j->t_y > GWIDTH) {
- X j->t_y = GWIDTH;
- X explode(j);
- X break;
- X }
- X
- X /* Make sure that player torps wobble */
- X if (j->t_status == TMOVE)
- X j->t_dir += (random() % 3) - 1;
- X
- X if (j->t_fuse-- <= 0) {
- X j->t_status = TFREE;
- X players[j->t_owner].p_ntorp--;
- X }
- X else if (near(j)) {
- X explode(j);
- X }
- X break;
- X case TDET:
- X j->t_x += (double) j->t_speed * Cos[j->t_dir] * WARP1;
- X if (j->t_x < 0)
- X j->t_x += GWIDTH;
- X else if (j->t_x > GWIDTH)
- X j->t_x -= GWIDTH;
- X j->t_y += (double) j->t_speed * Sin[j->t_dir] * WARP1;
- X if (j->t_y < 0)
- X j->t_y += GWIDTH;
- X else if (j->t_y > GWIDTH)
- X j->t_y -= GWIDTH;
- X explode(j);
- X break;
- X case TEXPLODE:
- X if (j->t_fuse-- <= 0) {
- X j->t_status = TFREE;
- X players[j->t_owner].p_ntorp--;
- X }
- X break;
- X case TOFF:
- X j->t_status = TFREE;
- X players[j->t_owner].p_ntorp--;
- X break;
- X }
- X }
- X}
- X
- X/* See if there is someone close enough to explode for */
- Xnear(torp)
- Xstruct torp *torp;
- X{
- X register int i;
- X int dx, dy;
- X register struct player *j;
- X
- X for (i = 0, j = &players[i]; i < MAXPLAYER; i++, j++) {
- X if (!(j->p_status == PALIVE))
- X continue;
- X if (torp->t_owner == j->p_no)
- X continue;
- X /* This is tricky. If you aren't at war with the team,
- X and that team is not at war with your team, continue.
- X */
- X if ((!(torp->t_war & j->p_team)) &&
- X (!(torp->t_team & (j->p_swar | j->p_hostile))))
- X continue;
- X dx = torp->t_x - j->p_x;
- X dy = torp->t_y - j->p_y;
- X if (ABS(dx) > EXPDIST || ABS(dy) > EXPDIST)
- X continue;
- X if (dx * dx + dy * dy < EXPDIST * EXPDIST)
- X return 1;
- X }
- X return 0;
- X}
- X
- X
- X
- X/* Do damage to all surrounding players */
- X
- Xexplode(torp)
- Xstruct torp *torp;
- X{
- X register int i;
- X int dx, dy, dist;
- X int damage;
- X register struct player *j;
- X
- X for (i = 0, j = &players[i]; i < MAXPLAYER; i++, j++) {
- X if (!(j->p_status == PALIVE))
- X continue;
- X if (torp->t_owner == j->p_no) /* This isn't realistic */
- X continue;
- X dx = torp->t_x - j->p_x;
- X dy = torp->t_y - j->p_y;
- X if (ABS(dx) > DETDIST || ABS(dy) > DETDIST) /*XXX*/
- X continue;
- X dist = dx * dx + dy * dy;
- X if (dist > DETDIST * DETDIST)
- X continue;
- X if (dist > EXPDIST * EXPDIST) {
- X damage = torp->t_damage * (DETDIST - sqrt((double) dist)) /
- X (DETDIST - EXPDIST);
- X }
- X else {
- X damage = torp->t_damage;
- X }
- X if (damage > 0) {
- X /* First, check to see if torp owner has started a war */
- X if (players[torp->t_owner].p_hostile & j->p_team) {
- X players[torp->t_owner].p_swar |= j->p_team;
- X }
- X /* Note that if a player is at peace with the victim, then
- X the torp has caused damage either accidently, or because
- X the victim was at war with, or hostile to, the player.
- X In either case, we don't consider the damage to be
- X an act of war */
- X
- X if (j->p_flags & PFSHIELD) {
- X j->p_shield -= damage;
- X if (j->p_shield < 0) {
- X j->p_damage -= j->p_shield;
- X j->p_shield = 0;
- X }
- X }
- X else {
- X j->p_damage += damage;
- X }
- X if (j->p_damage >= 100) {
- X j->p_status = PEXPLODE;
- X j->p_explode = 10/PLAYERFUSE;
- X if (!(j->p_flags & PFPRACTR)) {
- X players[torp->t_owner].p_kills += 1.0 +
- X j->p_armies * 0.1 + j->p_kills * 0.1;
- X }
- X killmess(j, &players[torp->t_owner]);
- X j->p_stats.st_losses++;
- X j->p_whydead = KTORP;
- X j->p_whodead = torp->t_owner;
- X }
- X }
- X }
- X torp->t_status = TEXPLODE;
- X torp->t_fuse = 10/TORPFUSE;
- X}
- X
- Xudplanets()
- X{
- X register int i;
- X register struct planet *l;
- X
- X for (i = 0, l = &planets[i]; i < MAXPLANETS; i++, l++) {
- X if (l->pl_couptime) /* Decrement coup counter one minute */
- X l->pl_couptime--;
- X if (l->pl_armies == 0)
- X continue;
- X if ((random() % 3000) < l->pl_armies)
- X l->pl_armies -= (random() % l->pl_armies);
- X if ((l->pl_armies < 4) && ((random() % 20) == 0)) {
- X l->pl_armies++;
- X continue;
- X }
- X if ((random() % 10) == 0)
- X l->pl_armies += (random() % 3) + 1;
- X
- X }
- X}
- X
- Xudphaser()
- X{
- X register int i;
- X register struct phaser *j;
- X register struct player *victim;
- X
- X for (i = 0, j = &phasers[i]; i < MAXPLAYER; i++, j++) {
- X switch (j->ph_status) {
- X case PHFREE:
- X continue;
- X case PHMISS:
- X if (j->ph_fuse-- == 1)
- X j->ph_status = PHFREE;
- X break;
- X case PHHIT:
- X if (j->ph_fuse-- == 10) {
- X victim = &players[j->ph_target];
- X
- X /* start a war, if necessary */
- X if (players[i].p_hostile & victim->p_team) {
- X players[i].p_swar |= victim->p_team;
- X }
- X
- X if (victim->p_flags & PFSHIELD) {
- X victim->p_shield -= j->ph_damage;
- X if (victim->p_shield < 0) {
- X victim->p_damage -= victim->p_shield;
- X victim->p_shield = 0;
- X }
- X }
- X else {
- X victim->p_damage += j->ph_damage;
- X }
- X if (victim->p_damage >= 100) {
- X victim->p_status = PEXPLODE;
- X victim->p_explode = 10/PLAYERFUSE;
- X if (!(victim->p_flags & PFPRACTR)) {
- X players[i].p_kills += 1.0 +
- X victim->p_armies * 0.1 +
- X victim->p_kills * 0.1;
- X }
- X killmess(victim, &players[i]);
- X victim->p_stats.st_losses++;
- X victim->p_whydead = KPHASER;
- X victim->p_whodead = i;
- X }
- X }
- X if (j->ph_fuse == 0)
- X j->ph_status = PHFREE;
- X break;
- X }
- X }
- X}
- X
- Xint pl_warning[MAXPLANETS]; /* To keep planets shut up for awhile */
- Xint tm_robots[MAXTEAM + 1]; /* To limit the number of robots */
- Xint tm_coup[MAXTEAM + 1]; /* To allow a coup */
- X
- Xteamtimers()
- X{
- X register int i;
- X for (i = 0; i <= MAXTEAM; i++) {
- X if (tm_robots[i] > 0)
- X tm_robots[i]--;
- X if (tm_coup[i] > 0)
- X tm_coup[i]--;
- X }
- X}
- X
- Xplfight()
- X{
- X register int h, i;
- X register struct player *j;
- X register struct planet *l;
- X int dx, dy;
- X int damage;
- X int dist;
- X int rnd;
- X char buf[80];
- X char buf1[80];
- X
- X for (h = 0, l = &planets[h]; h < MAXPLANETS; h++, l++) {
- X if (l->pl_flags & PLCOUP) {
- X l->pl_flags &= ~PLCOUP;
- X l->pl_owner = (l->pl_flags & ALLTEAM);
- X l->pl_armies = 4;
- X }
- X l->pl_flags &= ~PLREDRAW;
- X if (pl_warning[h] > 0)
- X pl_warning[h]--;
- X }
- X for (i = 0, j = &players[i]; i < MAXPLAYER; i++, j++) {
- X if (j->p_status == PALIVE) {
- X
- X /* Have planets do damage to nearby players. Note that
- X this is the most inefficient code in the game. If
- X one needs cycles, simply change the code to have
- X planets only attack ships that are in orbit. Thus
- X you get rid of the following for statement
- X */
- X for (h = 0, l = &planets[h]; h < MAXPLANETS; h++, l++) {
- X dx = ABS(l->pl_x - j->p_x);
- X dy = ABS(l->pl_y - j->p_y);
- X if (dx < 3 * PFIREDIST && dy < 3 * PFIREDIST)
- X l->pl_flags |= PLREDRAW;
- X if (dx > PFIREDIST || dy > PFIREDIST) /*XXX*/
- X continue;
- X dist = (int) hypot((double) dx, (double) dy);
- X if (dist > PFIREDIST)
- X continue;
- X if ((j->p_swar | j->p_hostile) & l->pl_owner) {
- X if (l->pl_armies > 0)
- X damage = l->pl_armies / 10 + 2;
- X else
- X damage = 0;
- X if (damage > 0) {
- X if (j->p_flags & PFSHIELD) {
- X j->p_shield -= damage;
- X if (j->p_shield < 0) {
- X j->p_damage -= j->p_shield;
- X j->p_shield = 0;
- X }
- X }
- X else {
- X j->p_damage += damage;
- X }
- X if (j->p_damage >= 100) {
- X j->p_explode = 10/PLAYERFUSE;
- X j->p_status = PEXPLODE;
- X j->p_stats.st_losses++;
- X (void) sprintf(buf, "%s (%c%x) killed by %s (%c)",
- X j->p_name,
- X teamlet[j->p_team],
- X j->p_no,
- X l->pl_name,
- X teamlet[l->pl_owner]);
- X pmessage(buf, 0, MALL, "GOD->ALL");
- X j->p_whydead = KPLANET;
- X j->p_whodead = h;
- X }
- X }
- X }
- X } /* End planet damage */
- X
- X /* do bombing */
- X if ((!(j->p_flags & PFORBIT)) || (!(j->p_flags & PFBOMB)))
- X continue;
- X l = &planets[j->p_planet];
- X if (j->p_team == l->pl_owner)
- X continue;
- X if (!((j->p_swar | j->p_hostile) & l->pl_owner))
- X continue;
- X if (l->pl_armies < 5)
- X continue;
- X
- X /* Warn owning team */
- X if (pl_warning[h] <= 0) {
- X pl_warning[h] = 50/PLFIGHTFUSE;
- X (void) sprintf(buf, "We are being attacked by %s %c%x.",
- X j->p_name,
- X teamlet[j->p_team],
- X j->p_no);
- X (void) sprintf(buf1, "%-3s->%-3s",
- X l->pl_name, teamshort[l->pl_owner]);
- X pmessage(buf, l->pl_owner, MTEAM, buf1);
- X }
- X
- X /* start the war (if necessary) */
- X j->p_swar |= l->pl_owner;
- X
- X rnd = random() % 100;
- X if (rnd < 50) {
- X continue;
- X }
- X else if (rnd < 80) {
- X l->pl_armies -= 1;
- X j->p_kills += 0.02;
- X j->p_stats.st_armsbomb++;
- X }
- X else if (rnd < 90) {
- X l->pl_armies -= 2;
- X j->p_kills += 0.04;
- X j->p_stats.st_armsbomb += 2;
- X }
- X else {
- X l->pl_armies -= 3;
- X j->p_kills += 0.06;
- X j->p_stats.st_armsbomb += 3;
- X }
- X
- X /* Send in a robot if there are no other defenders
- X and the planet is in the team's home space */
- X
- X if ((tcount[l->pl_owner] == 0) &&
- X (l->pl_flags & l->pl_owner) &&
- X tm_robots[l->pl_owner] == 0) {
- X rescue(l->pl_owner, j->p_kills);
- X tm_robots[l->pl_owner] = (1800 +
- X (random() % 1800)) /
- X TEAMFUSE;
- X }
- X }
- X }
- X}
- X
- Xbeam()
- X{
- X register int i;
- X register struct player *j;
- X register struct planet *l;
- X char buf[80];
- X char buf1[80];
- X
- X for (i = 0, j = &players[i]; i < MAXPLAYER; i++, j++) {
- X if ((j->p_status != PALIVE) || (!(j->p_flags & PFORBIT)))
- X continue;
- X l = &planets[j->p_planet];
- X if (j->p_flags & PFBEAMUP) {
- X if (l->pl_armies < 5)
- X continue;
- X if (j->p_armies == j->p_ship.s_maxarmies)
- X continue;
- X /* XXX */
- X if (j->p_armies == floor(j->p_kills * 2.0))
- X continue;
- X if (j->p_team != l->pl_owner)
- X continue;
- X if ((j->p_swar | j->p_hostile) & l->pl_owner)
- X continue;
- X j->p_armies++;
- X l->pl_armies--;
- X continue;
- X }
- X if (j->p_flags & PFBEAMDOWN) {
- X if (j->p_armies == 0)
- X continue;
- X if ((!((j->p_swar | j->p_hostile) & l->pl_owner))
- X && (j->p_team != l->pl_owner) && (l->pl_owner != NOBODY))
- X continue;
- X if (j->p_team != l->pl_owner) {
- X j->p_armies--;
- X if (l->pl_armies) {
- X int oldowner = l->pl_owner;
- X
- X /* start the war (if necessary) */
- X j->p_swar |= l->pl_owner;
- X
- X l->pl_armies--;
- X j->p_kills += 0.02;
- X j->p_stats.st_armsbomb++;
- X if (l->pl_armies == 0) {
- X /* Give planet to nobody */
- X (void) sprintf(buf, "%s destroyed by %s (%c%x)",
- X l->pl_name,
- X j->p_name,
- X teamlet[j->p_team],
- X j->p_no);
- X (void) sprintf(buf1, "%-3s->%-3s",
- X l->pl_name, teamshort[l->pl_owner]);
- X pmessage(buf, l->pl_owner, MTEAM, buf1);
- X l->pl_owner = NOBODY;
- X checkgen(oldowner, j);
- X }
- X }
- X else { /* planet taken over */
- X l->pl_armies++;
- X j->p_stats.st_planets++;
- X j->p_kills += 0.25;
- X (void) sprintf(buf, "%s taken over by %s (%c%x)",
- X l->pl_name,
- X j->p_name,
- X teamlet[j->p_team],
- X j->p_no);
- X l->pl_owner = j->p_team;
- X l->pl_info = j->p_team;
- X checkwin(j);
- X /* now tell new team */
- X (void) sprintf(buf1, "%-3s->%-3s",
- X l->pl_name, teamshort[l->pl_owner]);
- X pmessage(buf, l->pl_owner, MTEAM, buf1);
- X }
- X }
- X else {
- X j->p_armies--;
- X l->pl_armies++;
- X }
- X }
- X
- X }
- X}
- X
- Xblowup(sh)
- Xstruct player *sh;
- X{
- X register int i;
- X int dx, dy, dist;
- X int damage;
- X register struct player *j;
- X
- X for (i = 0, j = &players[i]; i < MAXPLAYER; i++, j++) {
- X if (j->p_status != PALIVE)
- X continue;
- X if (sh == j)
- X continue;
- X /* the following keeps people from blowing up on others */
- X me = sh;
- X if ((me->p_whydead == KQUIT) && (friendlyPlayer(j)))
- X continue;
- X dx = sh->p_x - j->p_x;
- X dy = sh->p_y - j->p_y;
- X if (ABS(dx) > DETDIST || ABS(dy) > DETDIST)
- X continue;
- X dist = dx * dx + dy * dy;
- X if (dist > DETDIST * DETDIST)
- X continue;
- X if (dist > EXPDIST * EXPDIST) {
- X damage = 100 * (DETDIST - sqrt((double) dist)) /
- X (DETDIST - EXPDIST);
- X }
- X else {
- X damage = 100;
- X }
- X if (damage > 0) {
- X if (j->p_flags & PFSHIELD) {
- X j->p_shield -= damage;
- X if (j->p_shield < 0) {
- X j->p_damage -= j->p_shield;
- X j->p_shield = 0;
- X }
- X }
- X else {
- X j->p_damage += damage;
- X }
- X if (j->p_damage >= 100) {
- X j->p_status = PEXPLODE;
- X j->p_explode = 10;
- X if (!(j->p_flags & PFPRACTR)) {
- X sh->p_kills += 1.0 +
- X j->p_armies * 0.1 + j->p_kills * 0.1;
- X }
- X killmess(j, sh);
- X j->p_stats.st_losses++;
- X j->p_whydead = KSHIP;
- X j->p_whodead = sh->p_no;
- X }
- X }
- X }
- X}
- X
- Xfreemem()
- X{
- X register int i;
- X register struct player *j;
- X
- X /* Blow players out of the game */
- X for (i = 0, j = &players[i]; i < MAXPLAYER; i++, j++) {
- X j->p_status = PDEAD;
- X j->p_whydead = KDAEMON;
- X j->p_ntorp = 0;
- X }
- X save_planets();
- X sleep(2);
- X shmctl(shmid, IPC_RMID, (struct shmid_ds *) 0);
- X exit(0);
- X}
- X
- Xsave_planets()
- X{
- X if (plfd >= 0) {
- X (void) lseek(plfd, (long) 0, 0);
- X (void) write(plfd, (char *) planets, sizeof(pdata));
- X }
- X}
- X/* This function checks to see if a team has been genocided --
- X their last planet has been beamed down to zero. It will set
- X a timer on their home planet that will prevent them from
- X couping for a random number of minutes.
- X*/
- Xcheckgen(loser, winner)
- Xint loser;
- Xstruct player *winner;
- X{
- X register int i;
- X register struct planet *l;
- X struct planet *homep;
- X
- X for (i = 0, l = &planets[i]; i < MAXPLANETS; i++, l++) {
- X if (l->pl_owner == loser)
- X return;
- X if (((l->pl_flags & ALLTEAM) == loser) && (l->pl_flags & PLHOME))
- X homep = l; /* Keep track of his home planet for marking */
- X }
- X
- X /* well, I guess they are losers. Hose them now */
- X winner->p_stats.st_genocides++;
- X homep->pl_couptime = (18000 + (random() % 18000)) / PLANETFUSE;
- X}
- X
- X
- X/* This function is called when a planet has been taken over.
- X It checks all the planets to see if the victory conditions
- X are right. If so, it blows everyone out of the game and
- X resets the galaxy
- X*/
- Xcheckwin(winner)
- Xstruct player *winner;
- X{
- X register int i, h;
- X register struct planet *l;
- X register struct player *j;
- X int team[MAXTEAM + 1];
- X
- X for (i = 0; i < 4; i++)
- X team[1<<i] = 0;
- X
- X for (i = 0, l = &planets[i]; i < MAXPLANETS; i++, l++)
- X team[l->pl_owner]++;
- X
- X for (i = 0; i < 4; i++) {
- X if (team[1<<i] >= VICTORY) {
- X /* We have a winning team */
- X for (h = 0, j = &players[0]; h < MAXPLAYER; h++, j++) {
- X j->p_status = PDEAD;
- X j->p_whydead = KWINNER;
- X j->p_whodead = winner->p_no;
- X j->p_ntorp = 0;
- X }
- X winner->p_stats.st_conqs++;
- X bcopy(pdata, planets, sizeof(pdata));
- X for (i = 0; i < 40; i++) {
- X if (random() % 4 == 0)
- X planets[i].pl_flags |= PLREPAIR;
- X if (random() % 2 == 0)
- X planets[i].pl_flags |= PLFUEL;
- X }
- X longjmp(env, 0);
- X }
- X }
- X}
- X
- Xpmessage(str, recip, group, addr)
- Xchar *str;
- Xint recip;
- Xint group;
- Xchar *addr;
- X{
- X struct message *cur;
- X
- X if (++(mctl->mc_current) >= MAXMESSAGE)
- X mctl->mc_current = 0;
- X cur = &messages[mctl->mc_current];
- X cur->m_no = mctl->mc_current;
- X cur->m_flags = group;
- X cur->m_time = ticks;
- X cur->m_recpt = recip;
- X (void) sprintf(cur->m_data, "%s %s", addr, str);
- X cur->m_flags |= MVALID;
- X}
- X
- Xghostmess(victim)
- X struct player *victim;
- X{
- X char buf[80];
- X static float ghostkills = 0.0;
- X
- X ghostkills += 1.0 + victim->p_armies * 0.1 + victim->p_kills * 0.1;
- X (void) sprintf(buf, "%s (%c%x) was kill %0.2f for the GhostBusters",
- X victim->p_name, teamlet[victim->p_team], victim->p_no, ghostkills);
- X pmessage(buf, 0, MALL, "GOD->ALL");
- X}
- X
- Xkillmess(victim, killer)
- Xstruct player *victim, *killer;
- X{
- X char buf[80];
- X
- X (void) sprintf(buf, "%s (%c%x) was kill %0.2f for %s (%c%x)",
- X victim->p_name,
- X teamlet[victim->p_team],
- X victim->p_no,
- X killer->p_kills,
- X killer->p_name,
- X teamlet[killer->p_team],
- X killer->p_no);
- X pmessage(buf, 0, MALL, "GOD->ALL");
- X}
- X
- X/* Send in a robot to avenge the aggrieved team */
- Xrescue(team, kills)
- Xint team;
- Xfloat kills;
- X{
- X char *arg1;
- X char *arg2 = "-lX";
- X
- X if (fork() == 0) {
- X (void) close(0);
- X (void) close(1);
- X (void) close(2);
- X (void) signal(SIGALRM, SIG_DFL);
- X switch (team) {
- X case FED:
- X arg1 = "-Tf";
- X break;
- X case ROM:
- X arg1 = "-Tr";
- X break;
- X case KLI:
- X arg1 = "-Tk";
- X break;
- X case ORI:
- X arg1 = "-To";
- X break;
- X }
- X if (kills > 9.0)
- X kills = 9.0;
- X (void) sprintf(arg2, "-l%d", (int) kills);
- X execl(ROBOT, "robot", arg1, arg2, 0);
- X /* If we get here, we are hosed anyway */
- X }
- X}
- X
- X#include <sys/resource.h>
- X
- X/* Don't fear the ... */
- X
- Xreaper(sig)
- X{
- X#ifdef hpux
- X wait((int *) 0);
- X#else hpux
- X while (wait3((union wait *) 0, WNOHANG, (struct rusage *) 0) > 0)
- X ;
- X#endif hpux
- X}
- X
- X#ifdef hpux
- X
- Xsrandom(foo)
- Xint foo;
- X{
- X rand(foo);
- X}
- X
- Xrandom()
- X{
- X return(rand());
- X}
- X
- Xgetrusage(foo, buf)
- Xint foo;
- Xstruct rusage *buf;
- X{
- X buf->ru_utime.tv_sec = 0;
- X buf->ru_stime.tv_sec = 0;
- X}
- X
- X#include <sys/signal.h>
- X
- Xint (*
- Xsignal(sig, funct))()
- Xint sig;
- Xint (*funct)();
- X{
- X struct sigvec vec, oldvec;
- X
- X sigvector(sig, 0, &vec);
- X vec.sv_handler = funct;
- X sigvector(sig, &vec, (struct sigvec *) 0);
- X}
- X
- X#endif hpux
- END_OF_daemon.c
- if test 29846 -ne `wc -c <daemon.c`; then
- echo shar: \"daemon.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f rmove.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"rmove.c\"
- else
- echo shar: Extracting \"rmove.c\" \(14954 characters\)
- sed "s/^X//" >rmove.c <<'END_OF_rmove.c'
- X
- X/*
- X
- X Copyright (c) 1986 Chris Guthrie
- X
- XPermission to use, copy, modify, and distribute this
- Xsoftware and its documentation for any purpose and without
- Xfee is hereby granted, provided that the above copyright
- Xnotice appear in all copies and that both that copyright
- Xnotice and this permission notice appear in supporting
- Xdocumentation. No representations are made about the
- Xsuitability of this software for any purpose. It is
- Xprovided "as is" without express or implied warranty.
- X
- X*/
- X
- X#include <X/Xlib.h>
- X#include <stdio.h>
- X#include <signal.h>
- X#include <math.h>
- X#include "defs.h"
- X#include "struct.h"
- X#include "data.h"
- X
- X#define SIZEOF(s) (sizeof (s) / sizeof (*(s)))
- X#define AVOID_TIME 4
- X#define AVOID_CLICKS 200
- X
- X#define NORMALIZE(d) ((((d) % 256) + 256) % 256)
- X
- X#define E_INTRUDER 0x01
- X#define E_TSHOT 0x02
- X#define E_PSHOT 0x04
- X
- Xstruct Enemy {
- X int e_info;
- X int e_dist;
- X unsigned char e_course; /* course to enemy */
- X unsigned char e_tcourse; /* torpedo intercept course to enemy */
- X unsigned int e_flags;
- X};
- X
- Xint timer;
- Xstatic int avoidTime;
- Xstatic unsigned short tok;
- X
- Xextern int debug;
- Xextern int hostile;
- Xextern int sticky;
- Xextern int practice;
- X
- Xunsigned char getcourse();
- X
- Xrmove()
- X{
- X register int i;
- X register int burst;
- X register int numHits, tDir;
- X int avDir;
- X extern struct Enemy *get_nearest();
- X struct Enemy *enemy_buf;
- X struct player *enemy;
- X static int clock = 0;
- X static int avoid[2] = { -32, 32 };
- X int no_cloak;
- X
- X clock++;
- X /* Check that I'm alive */
- X if (me->p_status == PEXPLODE) {
- X signal(SIGALRM, SIG_IGN);
- X while (me->p_status == PEXPLODE)
- X ;
- X while (me->p_ntorp > 0)
- X ;
- X me->p_status = PFREE;
- X exit(0);
- X }
- X if (me->p_status == PDEAD) {
- X signal(SIGALRM, SIG_IGN);
- X me->p_status = PFREE;
- X exit(0);
- X }
- X
- X /* keep ghostbuster away */
- X me->p_ghostbuster = 0;
- X
- X /* Find an enemy */
- X
- X enemy_buf = get_nearest();
- X
- X if (enemy_buf > 0) { /* Someone to kill */
- X enemy = &players[enemy_buf->e_info];
- X timer = 0;
- X if (debug)
- X fprintf(stderr, "%d) noticed %d\n", me->p_no, enemy->p_no);
- X }
- X else if (enemy_buf < 0) { /* no more players. wait 1 minute. */
- X if (!sticky) {
- X if (timer == 0)
- X timer = me->p_updates + 600;
- X if (me->p_updates >= timer) {
- X signal(SIGALRM, SIG_IGN);
- X me->p_status = PFREE;
- X exit(0);
- X }
- X }
- X if (do_repair()) {
- X return;
- X }
- X go_home(0);
- X if (debug)
- X fprintf(stderr, "%d) No players in game.\n", me->p_no);
- X return;
- X }
- X else if (enemy_buf == 0) { /* no one hostile */
- X if (debug)
- X fprintf(stderr, "%d) No hostile players in game.\n", me->p_no);
- X if (do_repair()) {
- X return;
- X }
- X go_home(0);
- X timer = 0;
- X return;
- X }
- X
- X/* Algorithm:
- X** We have an enemy.
- X** First priority: shoot at target in range.
- X** Second: Dodge torps.
- X** Third: Get away if we are damaged.
- X** Fourth: repair.
- X** Fifth: attack.
- X*/
- X
- X/*
- X** If we are a practice robot, we will do all but the second. One
- X** will be modified to shoot poorly and not use phasers.
- X**/
- X /* Fire weapons!!! */
- X /*
- X ** get_nearest() has already determined if torpedoes and phasers
- X ** will hit. It has also determined the courses which torps and
- X ** phasers should be fired. If so we will go ahead and shoot here.
- X ** We will lose repair and cloaking for the rest of this interrupt.
- X ** if we fire here.
- X */
- X
- X if (practice) {
- X no_cloak = 1;
- X if (enemy_buf->e_flags & E_TSHOT) {
- X if (debug)
- X fprintf(stderr, "%d) firing torps\n", me->p_no);
- X for (burst = 0; (burst < 3) && (me->p_ntorp < MAXTORP); burst++) {
- X tok += 11;
- X ntorp(enemy_buf->e_tcourse, TMOVE, tok);
- X }
- X }
- X }
- X else {
- X no_cloak = 0;
- X if (enemy_buf->e_flags & E_TSHOT) {
- X if (debug)
- X fprintf(stderr, "%d) firing torps\n", me->p_no);
- X for (burst = 0; (burst < 2) && (me->p_ntorp < MAXTORP); burst++) {
- X repair_off();
- X cloak_off();
- X tok += 11;
- X ntorp(enemy_buf->e_tcourse, TSTRAIGHT, tok);
- X no_cloak++;
- X }
- X }
- X if (enemy_buf->e_flags & E_PSHOT) {
- X if (debug)
- X fprintf(stderr, "%d) phaser firing\n", me->p_no);
- X no_cloak++;
- X repair_off();
- X cloak_off();
- X phaser(enemy_buf->e_course);
- X }
- X }
- X
- X /* Avoid torps */
- X /*
- X ** This section of code allows robots to avoid torps.
- X ** Within a specific range they will check to see if
- X ** any of the 'closest' enemies torps will hit them.
- X ** If so, they will evade for four updates.
- X ** Evading is all they will do for this round, other than shooting.
- X */
- X
- X if (!practice) {
- X if (enemy->p_ntorp < 5) {
- X if ((enemy_buf->e_dist < 15000) || (avoidTime > 0)) {
- X numHits = projectDamage(enemy->p_no, &avDir);
- X if (debug) {
- X fprintf(stderr, "%d hits expected from %d from dir = %d\n",
- X numHits, enemy->p_no, avDir);
- X }
- X if (numHits == 0) {
- X if (--avoidTime > 0) { /* we may still be avoiding */
- X if (angdist(me->p_desdir, me->p_dir) > 64)
- X me->p_desspeed = 3;
- X else
- X me->p_desspeed = 5;
- X return;
- X }
- X } else {
- X /*
- X * Actually avoid Torps
- X */
- X avoidTime = AVOID_TIME;
- X tDir = avDir - me->p_dir;
- X /* put into 0->255 range */
- X tDir = NORMALIZE(tDir);
- X if (debug)
- X fprintf(stderr, "mydir = %d avDir = %d tDir = %d q = %d\n",
- X me->p_dir, avDir, tDir, tDir / 64);
- X switch (tDir / 64) {
- X case 0:
- X case 1:
- X me->p_desdir = NORMALIZE(avDir + 64);
- X break;
- X case 2:
- X case 3:
- X me->p_desdir = NORMALIZE(avDir - 64);
- X break;
- X }
- X if (!no_cloak)
- X cloak_on();
- X
- X if (angdist(me->p_desdir, me->p_dir) > 64)
- X me->p_desspeed = 3;
- X else
- X me->p_desspeed = 5;
- X
- X shield_up();
- X if (debug)
- X fprintf(stderr, "evading to dir = %d\n", me->p_desdir);
- X return;
- X }
- X }
- X }
- X
- X /*
- X ** Trying another scheme.
- X ** Robot will keep track of the number of torps a player has
- X ** launched. If they are greater than say four, the robot will
- X ** veer off immediately. Seems more humanlike to me.
- X */
- X
- X else if (enemy_buf->e_dist < 15000) {
- X if (--avoidTime > 0) { /* we may still be avoiding */
- X if (angdist(me->p_desdir, me->p_dir) > 64)
- X me->p_desspeed = 3;
- X else
- X me->p_desspeed = 5;
- X return;
- X }
- X if (random() % 2) {
- X me->p_desdir = NORMALIZE(enemy_buf->e_course - 64);
- X avoidTime = AVOID_TIME;
- X }
- X else {
- X me->p_desdir = NORMALIZE(enemy_buf->e_course + 64);
- X avoidTime = AVOID_TIME;
- X }
- X if (angdist(me->p_desdir, me->p_dir) > 64)
- X me->p_desspeed = 3;
- X else
- X me->p_desspeed = 5;
- X shield_up();
- X return;
- X }
- X }
- X
- X /* Run away */
- X /*
- X ** The robot has taken damage. He will now attempt to run away from
- X ** the closest player. This obviously won't do him any good if there
- X ** is another player in the direction he wants to go.
- X ** Note that the robot will not run away if he dodged torps, above.
- X ** The robot will lower his shields in hopes of repairing some damage.
- X */
- X
- X if (me->p_damage > 0 && enemy_buf->e_dist < 13000) {
- X if (me->p_etemp > 900) /* 90% of 1000 */
- X me->p_desspeed = 5;
- X else
- X me->p_desspeed = 6;
- X if (!no_cloak)
- X cloak_on();
- X repair_off();
- X shield_down();
- X me->p_desdir = enemy_buf->e_course - 128;
- X if (debug)
- X fprintf(stderr, "%d(%d)(%d/%d) running from %c%d %16s damage (%d/%d) dist %d\n",
- X me->p_no,
- X (int) me->p_kills,
- X me->p_damage,
- X me->p_shield,
- X teamlet[enemy->p_team],
- X enemy->p_no,
- X enemy->p_login,
- X enemy->p_damage,
- X enemy->p_shield,
- X enemy_buf->e_dist);
- X return;
- X }
- X
- X /* Repair if necessary (we are safe) */
- X /*
- X ** The robot is safely away from players. It can now repair in peace.
- X ** It will try to do so now.
- X */
- X
- X if (do_repair()) {
- X return;
- X }
- X
- X /* Attack. */
- X /*
- X ** The robot has nothing to do. It will check and see if the nearest
- X ** enemy fits any of its criterion for attack. If it does, the robot
- X ** will speed in and deliver a punishing blow. (Well, maybe)
- X */
- X
- X if ((enemy_buf->e_flags & E_INTRUDER) || (enemy_buf->e_dist < 15000)
- X || (hostile)) {
- X if ((!no_cloak) && (enemy_buf->e_dist < 10000))
- X cloak_on();
- X shield_up();
- X if (debug)
- X fprintf(stderr, "%d(%d)(%d/%d) attacking %c%d %16s damage (%d/%d) dist %d\n",
- X me->p_no,
- X (int) me->p_kills,
- X me->p_damage,
- X me->p_shield,
- X teamlet[enemy->p_team],
- X enemy->p_no,
- X enemy->p_login,
- X enemy->p_damage,
- X enemy->p_shield,
- X enemy_buf->e_dist);
- X
- X if (enemy_buf->e_dist < 15000) {
- X me->p_desdir = enemy_buf->e_course +
- X avoid[(clock / AVOID_CLICKS) % SIZEOF(avoid)];
- X if (angdist(me->p_desdir, me->p_dir) > 64)
- X me->p_desspeed = 3;
- X else
- X me->p_desspeed = 4;
- X }
- X else {
- X me->p_desdir = enemy_buf->e_course;
- X if (angdist(me->p_desdir, me->p_dir) > 64)
- X me->p_desspeed = 3;
- X else if (me->p_etemp > 900) /* 90% of 1000 */
- X me->p_desspeed = 5;
- X else
- X me->p_desspeed = 6;
- X }
- X }
- X else {
- X go_home(enemy_buf);
- X }
- X}
- X
- Xunsigned char
- Xgetcourse(x, y)
- Xint x, y;
- X{
- X return((unsigned char) (atan2((double) (x - me->p_x),
- X (double) (me->p_y - y)) / 3.14159 * 128.));
- X}
- X
- Xstruct {
- X int x;
- X int y;
- X} center[] = { {0, 0},
- X {GWIDTH / 4, GWIDTH * 3 / 4}, /* Fed */
- X {GWIDTH / 4, GWIDTH / 4}, /* Rom */
- X {0, 0},
- X {GWIDTH * 3 / 4, GWIDTH / 4}, /* Kli */
- X {0, 0},
- X {0, 0},
- X {0, 0},
- X {GWIDTH * 3 / 4, GWIDTH * 3 / 4}}; /* Ori */
- X
- X/* This function means that the robot has nothing better to do.
- X If there are hostile players in the game, it will try to get
- X as close to them as it can, while staying in it's on space.
- X Otherwise, it will head to the center of its own space.
- X*/
- Xgo_home(ebuf)
- Xstruct Enemy *ebuf;
- X{
- X int x, y, speed;
- X double dx, dy;
- X int tdist;
- X struct player *j;
- X
- X if (ebuf == 0) { /* No enemies */
- X if (debug)
- X fprintf(stderr, "%d) No enemies\n", me->p_no);
- X x = center[me->p_team].x;
- X y = center[me->p_team].y;
- X }
- X else { /* Let's get near him */
- X j = &players[ebuf->e_info];
- X x = j->p_x;
- X y = j->p_y;
- X switch (me->p_team) {
- X case FED:
- X if (x > (GWIDTH/2) - 5000)
- X x = (GWIDTH/2) - 5000;
- X if (y < (GWIDTH/2) + 5000)
- X y = (GWIDTH/2) + 5000;
- X break;
- X case ROM:
- X if (x > (GWIDTH/2) - 5000)
- X x = (GWIDTH/2) - 5000;
- X if (y > (GWIDTH/2) - 5000)
- X y = (GWIDTH/2) - 5000;
- X break;
- X case KLI:
- X if (x < (GWIDTH/2) + 5000)
- X x = (GWIDTH/2) + 5000;
- X if (y > (GWIDTH/2) - 5000)
- X y = (GWIDTH/2) - 5000;
- X break;
- X case ORI:
- X if (x < (GWIDTH/2) + 5000)
- X x = (GWIDTH/2) + 5000;
- X if (y < (GWIDTH/2) + 5000)
- X y = (GWIDTH/2) + 5000;
- X break;
- X }
- X }
- X if (debug)
- X fprintf(stderr, "%d) moving towards (%d/%d)\n",
- X me->p_no, x, y);
- X
- X /* Note that I've decided that robots should never stop moving.
- X ** It makes them too easy to kill
- X */
- X
- X me->p_desdir = getcourse(x, y);
- X if (angdist(me->p_desdir, me->p_dir) > 64)
- X me->p_desspeed = 3;
- X else if (me->p_etemp > 900) /* 90% of 1000 */
- X me->p_desspeed = 5;
- X else {
- X dx = x - me->p_x;
- X dy = y - me->p_y;
- X me->p_desspeed = (hypot(dx, dy) / 5000) + 3;
- X }
- X cloak_off();
- X}
- X
- XprojectDamage(eNum, dirP)
- X int *dirP;
- X{
- X register int i, j, numHits = 0, mx, my, tx, ty, dx, dy;
- X double tdx, tdy, mdx, mdy;
- X register struct torp *t;
- X
- X *dirP = 0;
- X for (i = 0, t = &torps[eNum * MAXTORP]; i < MAXTORP; i++, t++) {
- X if (t->t_status == TFREE)
- X continue;
- X tx = t->t_x; ty = t->t_y;
- X mx = me->p_x; my = me->p_y;
- X tdx = (double) t->t_speed * Cos[t->t_dir] * WARP1;
- X tdy = (double) t->t_speed * Sin[t->t_dir] * WARP1;
- X mdx = (double) me->p_speed * Cos[me->p_dir] * WARP1;
- X mdy = (double) me->p_speed * Sin[me->p_dir] * WARP1;
- X for (j = t->t_fuse; j > 0; j--) {
- X tx += tdx; ty += tdy;
- X mx += mdx; my += mdy;
- X dx = tx - mx; dy = ty - my;
- X if (ABS(dx) < EXPDIST && ABS(dy) < EXPDIST) {
- X numHits++;
- X *dirP += t->t_dir;
- X break;
- X }
- X }
- X }
- X if (numHits > 0)
- X *dirP /= numHits;
- X return (numHits);
- X}
- X
- Xstruct Enemy ebuf;
- X
- Xstruct Enemy *
- Xget_nearest()
- X{
- X int pcount = 0;
- X register int i;
- X register struct player *j;
- X int intruder = 0;
- X int tdist;
- X double dx, dy;
- X
- X /* Find an enemy */
- X ebuf.e_info = me->p_no;
- X ebuf.e_dist = GWIDTH + 1;
- X
- X pcount = 0; /* number of human players in game */
- X
- X /* avoid dead slots, me, other robots (which aren't hostile) */
- X for (i = 0, j = &players[i]; i < MAXPLAYER; i++, j++) {
- X if ((j->p_status != PALIVE) || (j == me) ||
- X ((j->p_flags & PFROBOT) && (!hostile)))
- X continue;
- X else
- X pcount++; /* Other players in the game */
- X if (((j->p_swar | j->p_hostile) & me->p_team)
- X || ((me->p_swar | me->p_hostile) & j->p_team)) {
- X /* We have an enemy */
- X /* Get his range */
- X dx = j->p_x - me->p_x;
- X dy = j->p_y - me->p_y;
- X tdist = hypot(dx, dy);
- X
- X /* Check to see if ship is in our space. */
- X switch (me->p_team) {
- X case FED:
- X intruder = ((j->p_x < GWIDTH/2) && (j->p_y > GWIDTH/2));
- X break;
- X case ROM:
- X intruder = ((j->p_x < GWIDTH/2) && (j->p_y < GWIDTH/2));
- X break;
- X case KLI:
- X intruder = ((j->p_x > GWIDTH/2) && (j->p_y < GWIDTH/2));
- X break;
- X case ORI:
- X intruder = ((j->p_x > GWIDTH/2) && (j->p_y > GWIDTH/2));
- X break;
- X }
- X
- X if (tdist < ebuf.e_dist) {
- X ebuf.e_info = i;
- X ebuf.e_dist = tdist;
- X if (intruder)
- X ebuf.e_flags |= E_INTRUDER;
- X else
- X ebuf.e_flags &= ~(E_INTRUDER);
- X }
- X }
- X }
- X if (pcount == 0)
- X return ((struct Enemy *) -1); /* no players in game */
- X else if (ebuf.e_info == me->p_no)
- X return (0); /* no hostile players in the game */
- X else {
- X j = &players[ebuf.e_info];
- X
- X /* Get torpedo course to nearest enemy */
- X ebuf.e_flags &= ~(E_TSHOT);
- X for (i = 0; i < 50; i++) {
- X double he_x, he_y, area;
- X
- X he_x = j->p_x + Cos[j->p_dir] * j->p_speed * i * WARP1;
- X he_y = j->p_y + Sin[j->p_dir] * j->p_speed * i * WARP1;
- X area = i * me->p_ship.s_torpspeed * WARP1;
- X if (hypot(he_x - me->p_x, he_y - me->p_y) < area) {
- X ebuf.e_flags |= E_TSHOT;
- X ebuf.e_tcourse = getcourse((int) he_x, (int) he_y);
- X break;
- X }
- X }
- X /*
- X if (debug)
- X fprintf(stderr, "torpedo course to enemy %d is %d (%d) - %s\n",
- X j->p_no,
- X (int) ebuf.e_tcourse,
- X (int) ebuf.e_tcourse * 360 / 256,
- X (ebuf.e_flags & E_TSHOT) ? "aiming to hit" :
- X "no hit possible");
- X */
- X
- X /* Get phaser shot status */
- X if (ebuf.e_dist < 5000)
- X ebuf.e_flags |= E_PSHOT;
- X else
- X ebuf.e_flags &= ~(E_PSHOT);
- X
- X /* get course info */
- X ebuf.e_course = getcourse(j->p_x, j->p_y);
- X /*
- X if (debug)
- X fprintf(stderr, "Set course to enemy is %d (%d)\n",
- X (int)ebuf.e_course,
- X (int) ebuf.e_course * 360 / 256);
- X */
- X
- X return (&ebuf);
- X }
- X}
- X
- Xdo_repair()
- X{
- X/* Repair if necessary (we are safe) */
- X
- X if (me->p_damage > 0) {
- X me->p_desspeed = 0;
- X cloak_off();
- X shield_down();
- X me->p_desspeed = 0;
- X if (me->p_speed == 0)
- X repair();
- X if (debug)
- X fprintf(stderr, "%d) repairing damage at %d\n",
- X me->p_no,
- X me->p_damage);
- X return(1);
- X }
- X else {
- X return (0);
- X }
- X}
- END_OF_rmove.c
- if test 14954 -ne `wc -c <rmove.c`; then
- echo shar: \"rmove.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f xtrek.6 -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"xtrek.6\"
- else
- echo shar: Extracting \"xtrek.6\" \(472 characters\)
- sed "s/^X//" >xtrek.6 <<'END_OF_xtrek.6'
- X.TH XTREK 6 "19 Sept 1986"
- X.SH NAME
- Xxtrek \- X based multi-player space shoot 'em up game
- X.SH SYNOPSIS
- X.B xtrek
- X[ monitor:0 ]
- X.SH DESCRIPTION
- X.I Xtrek
- Xis a game based on shared memory and the X window environment.
- XIt is thoroughly described in xtrek.doc which probably lives
- Xin /usr/games/lib/xtrek/xtrek.doc.
- X.SH OPTIONS
- X.I Xtrek
- Xwill get the monitor name from your environment unless
- Xit is specified on the command line.
- X.SH AUTHOR
- XChris Guthrie (chris@ic.berkeley.edu)
- END_OF_xtrek.6
- if test 472 -ne `wc -c <xtrek.6`; then
- echo shar: \"xtrek.6\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- echo shar: End of archive 1 \(of 6\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 2 3 4 5 6 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 6 archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-
-